/**模块标识符 */
// 在Node.js中，模块标识符是用于标识和引用模块的字符串。在使用require函数加载模块时，需要使用模块标识符来指定要加载的模块。模块标识符可以是以下几种形式之一：
// 核心模块的标识符，例如：'http'、'fs'、'path'等，用于引用Node.js内置的核心模块。
// 相对路径或绝对路径，用于引用项目中的自定义模块或第三方模块。相对路径以'./'或'../'开头，表示相对于当前文件的路径；绝对路径以'/'开头，表示绝对路径。
// npm包的名称，用于引用已安装的npm包。当使用npm安装包时，可以直接使用包的名称作为模块标识符来引用该包。
// 例如，在Node.js中，可以使用以下方式来引用模块：
// 引用核心模块
var http = require('http');

// 引用相对路径的自定义模块
var myModule = require('./myModule');

// 引用npm包
var lodash = require('lodash');

/**异步依赖 */
// 异步依赖的典型场景包括：
// 动态加载模块：在运行时根据条件或事件需要动态加载依赖的模块。
// 按需加载资源：根据用户操作或页面状态需要异步加载相关资源，如图片、样式表、脚本等。
// 懒加载组件：在页面滚动或交互时，按需加载页面中的组件或模块。
// 在异步依赖的情况下，通常会使用异步加载的方式来引入依赖，
// 以避免阻塞主线程或提高页面加载性能。这可能涉及到使用动态import语句（ES6模块）、require.ensure（Webpack）、System.import（SystemJS）等机制来实现异步加载。

/**模块加载qi */

// RequireJS：一个用于在浏览器中实现模块化开发的模块加载器，支持AMD（Asynchronous Module Definition）规范，可以异步加载模块。

// SystemJS：一个通用的模块加载器，支持加载各种模块格式（包括AMD、CommonJS、ES6等），可以在浏览器和Node.js环境中使用。

// webpack：虽然webpack更多地被认为是一个模块打包工具，但它也具有模块加载器的功能，可以通过各种loader加载各种类型的文件，并支持异步加载模块。

// Browserify：一个用于在浏览器中使用CommonJS模块的工具，可以将Node.js风格的模块打包成浏览器可用的格式。

/**ES6模块 */

// 导出和导入：使用export关键字将模块中的变量、函数或类导出，使用import关键字引入其他模块导出的内容。

// 静态解析：ES6模块的导入和导出是静态的，意味着它们在代码解析阶段就能确定模块之间的依赖关系，这有助于提高性能和可靠性。

// 单一实例：每个ES6模块都有自己的顶级作用域，模块中的变量不会泄漏到全局作用域，这有助于避免命名冲突和全局污染。

// 默认导出：除了可以导出多个变量、函数或类外，ES6模块还支持默认导出，使得一个模块可以有一个默认的导出值。

// 动态导入：ES6模块还支持动态导入，可以在运行时异步加载模块。
// math.js
export const sum = (a, b) => a + b;
export const multiply = (a, b) => a * b;

// app.js
import { sum, multiply } from './math.js';

console.log(sum(2, 3)); // 输出 5
console.log(multiply(2, 3)); // 输出 6


/**模块标签及定义 */

// CommonJS（Node.js）:

// 模块标签：module.exports、exports
// 定义：使用module.exports或exports关键字来导出模块内容，使用require函数来导入模块。
// ES6模块：

// 模块标签：export、import
// 定义：使用export关键字将模块中的变量、函数或类导出，使用import关键字引入其他模块导出的内容。
// AMD（Asynchronous Module Definition）:

// 模块标签：define、require
// 定义：使用define函数定义模块，使用require函数异步加载模块。
// UMD（Universal Module Definition）:

// 模块标签：(function (root, factory) { ... })(this, function (...) { ... })
// 定义：通过一个通用的模式，兼容CommonJS、AMD和全局变量的方式来定义模块。

/**
 * import './aa.js'
   export * from './aa.js'的区别 
*/

// import './aa.js' 语句用于导入指定模块的内容，但不会将该模块的导出内容重新导出到当前模块。它只是简单地加载了目标模块，使得目标模块中的代码可以在当前模块中使用。
// export * from './aa.js' 语句用于重新导出指定模块的所有导出内容。这意味着当前模块会将目标模块中的所有导出内容重新导出，使得其他模块可以通过当前模块访问目标模块的导出内容。
// aa.js
export const foo = 'foo';
export const bar = 'bar';
// 如果在另一个模块中使用 import './aa.js'，则可以在当前模块中直接使用 foo 和 bar 变量。
// 而如果使用 export * from './aa.js'，则当前模块会重新导出 aa.js 模块中的所有导出内容，其他模块可以通过当前模块访问 foo 和 bar 变量。
// 总之，import './aa.js' 是用于导入模块的语句，而 export * from './aa.js' 是用于重新导出指定模块的所有导出内容。